[% setvar title Improved parsing and flexibility of indirect object syntax %]
<div id="archive-notice">
    <h3>This file is part of the Perl 6 Archive</h3>
    <p>To see what is currently happening visit <a href="http://www.perl6.org/">http://www.perl6.org/</a></p>
</div>
<div class='pod'>
<a name='TITLE'></a><h1>TITLE</h1>
<p>Improved parsing and flexibility of indirect object syntax</p>
<a name='VERSION'></a><h1>VERSION</h1>
<pre>   Maintainer: Nathan Wiger &lt;<a href='mailto:nate@wiger.org'>nate@wiger.org</a>&gt;
   Date: 29 Aug 2000
   Last Modified: 29 Sep 2000
   Mailing List: <a href='mailto:perl6-language-objects@perl.org'>perl6-language-objects@perl.org</a>
   Number: 174
   Version: 3
   Status: Frozen</pre>
<a name='ABSTRACT'></a><h1>ABSTRACT</h1>
<p>Currently, Perl 5 makes a distinction between routines called in the
indirect object vs. function form:</p>
<pre>   $r = new CGI;          # CGI-&gt;new
   $r = new CGI (@args);  # CGI-&gt;new(@args)
   $r = new(CGI  @args);  # mail::new(main::CGI(@args))</pre>
<p>This causes many problems, such as having to have special prototypes
that translate the optional first argument object into the indirect
object syntax. Special cases like this, and the inability to prototype</p>
<pre>   print(HANDLE @list);</pre>
<p>Have led some to suggest indirect objects be expunged altogether.</p>
<p>However, inflexbility is not the solution to this problem, since there
are many benefits to indirect object syntax. In Perl 6, the distinction
between function and indirect object syntax should be dropped. Instead,
the second form should be automatically translated to the first when
possible. This increased flexibility allows prototyping of key functions
while still being able to take advantage of indirect objects.</p>
<a name='DESCRIPTION'></a><h1>DESCRIPTION</h1>
<a name='Indirect objects should be any valid single value'></a><h2>Indirect objects should be any valid single value</h2>
<p>Currently, indirect objects can only be a scalar, block, or bareword.
This RFC proposes that this concept be extended to any valid singular
thingy. So in Perl 6 these:</p>
<pre>   print $handles{'mainout'} &quot;Hello, world!&quot;;
   print $output[0] &quot;Hi there!&quot;;</pre>
<p>Should work as indirect objects. Code references should still have to be
enclosed in blocks, since this is needed to reduce ambiguity between
indirect objects and chained functions.</p>
<a name='Indirect objects should be enclosable in parens'></a><h2>Indirect objects should be enclosable in parens</h2>
<p>Let's get into a more common example:</p>
<pre>   print @data;
   print(@data); 
   print STDERR @data;
   print(STDERR @data);</pre>
<p>Currently, the fact that all of these can coexist contributes to the
fact that CORE::print is not prototypeable/overrideable, which is a bad
thing, obviously. That last one is particularly sticky, since it would
intrinsically be parsed as something like:</p>
<pre>   CORE::print(main::STDERR(@data));</pre>
<p>But now we have to have special rules to deal with this. I'm going to
digress for a moment and skip barewords, coming back to them later.</p>
<p>Assuming that the above became scalar filehandles:</p>
<pre>   print $STDERR @data;
   print($STDERR @data);</pre>
<p>We can add a simple parsing rule to convert the second form into the
first:</p>
<pre>   If the first argument to a function is a scalar value which
   is not followed by a comma, then that value is the indirect
   object for that function.</pre>
<p>So, under this rule, the above two would both become:</p>
<pre>   $STDERR-&gt;print(@data);</pre>
<p>Assuming that print really did work as a true indirect object. This rule
generalizes to any function:</p>
<pre>   clone($obj @args);          # $obj-&gt;clone(@args)
   mogrify($trans[0] @stuff);  # $trans[0]-&gt;mogrify(@stuff);</pre>
<p>So, this allows us to use the current <code>print(HANDLE @data)</code> form
without special parsing rules. Notice that this rule does <i>not</i> allow
you to do this:</p>
<pre>   do_stuff(@data);</pre>
<p>and expect Perl to magically figure out that <code>$data[0]</code> is an object
reference. That's just <i>too weird</i>. The first argument <i>must</i> be a
scalar without a trailing comma.</p>
<a name='Why this is a needed'></a><h2>Why this is a needed</h2>
<p>At first, this may seem like syntactic sugar. It's not, it's much more
than that.</p>
<p>In fact, this makes Perl 6 much more flexible and reduces the number of
core methods, without confusing the end user with inconsistent syntax.
In fact, methods such as <code>close</code> and <code>open</code> could leave core
altogether, instead being called on the objects:</p>
<pre>   $FILE = open(http &quot;<a href='http://www.yahoo.com/' target='_blank'>www.yahoo.com</a>&quot;);  # http-&gt;open
   close($FILE);                                # $FILE-&gt;close</pre>
<p>It should be obvious what the benefits of being able to do this are.</p>
<p>It makes the core syntax much more flexible, and reduces the need
to include simple translator prototypes. This makes <b>RFC 168:
Built-in functions should be functions</b>, much more realistic since
these prototypes no longer have to handle the special case of an
&quot;optional first argument object&quot;. For example:</p>
<pre>   print($STDOUT @data)   becomes   $STDOUT-&gt;print(@data);</pre>
<p>automatically via parsing, meaning that CORE::print can be a
prototypeable function.</p>
<a name='Ambiguity: Bareword indirect object'></a><h3>Ambiguity: Bareword indirect object</h3>
<p>The following ambiguity exists in Perl 5 which is neither solved nor
made worse by this RFC. However, it is worth addressing since we're
talking about indirect objects.</p>
<p>When the indirect object is a bareword, considerable ambiguity exists
which can actually be quite difficult to resolve cleanly:</p>
<pre>   $p = new Person name =&gt; $name, age =&gt; $age;</pre>
<p>The above example is valid in Perl 5. However, it can be difficult to
read and maintain, and many people would promote disambiguating it in
one of the following ways:</p>
<pre>   $p = new Person (name =&gt; $name, age =&gt; $age);
   $p = new {Person} name =&gt; $name, age =&gt; $age;
   $p = Person-&gt;new(name =&gt; $name, age =&gt; $age);</pre>
<p>Under this RFC, you would be able to write this as well:</p>
<pre>   $p = new(Person name =&gt; $name, age =&gt; $age);</pre>
<p>However, note that like the first disambiguating case above, you are
still stricken with the problem that if the person defines
<code>main::Person</code>, that will be called, and not your indirect object,
resulting in parsing as such:</p>
<pre>   $p = main::new(main::Person(name =&gt; $name, age =&gt; $age));</pre>
<p><b>RFC 244</b> suggests that the bareword indirect object be dropped
altogether to resolve this ambiguity. While I do find this disturbing in
a way, it is hardly the only syntactic ambiguity in Perl and bareword
indirect objects are, in most cases, is quite useful.</p>
<p>Because this RFC neither helps nor hurts this specific ambiguity, it
defers to whatever is decided with barewords and simply states: The
precedence rules for bareword indirect objects inside parens should be
the same as for those outside parens.</p>
<a name='IMPLEMENTATION'></a><h1>IMPLEMENTATION</h1>
<p>Add the singular rule:</p>
<pre>   If the first argument to a function is a scalar value which
   is not followed by a comma, then that value is the indirect
   object for that function.</pre>
<p>To Perl's parsing. Changes to <code>toke.c</code> (or the equivalent in Perl 6)
would be required.</p>
<a name='MIGRATION'></a><h1>MIGRATION</h1>
<p>This introduces new functionality that does not break any existing code.
No translation should be required.</p>
<a name='REFERENCES'></a><h1>REFERENCES</h1>
<p>RFC 14:  Modify open() to support FileObjects and Extensibility</p>
<p>RFC 168: Built-in functions should be functions</p>
<p>RFC 244: Method calls should not suffer from the action on a distance</p>
<p><a href='http://www.mail-archive.com/perl6-language@perl.org/msg03186.html' target='_blank'>www.mail-archive.com</a></p>
<p><a href='http://www.mail-archive.com/perl6-language-objects@perl.org/msg00097.html' target='_blank'>www.mail-archive.com</a></p>
</div>
